﻿using System;
using System.Collections.Generic;
using System.Linq;
using Autodesk.AutoCAD.Customization;

namespace AutoCADDotNetLibrary
{
    /// <summary>
    /// 根据AutoCAD2010的dll进行的转换
    /// </summary>
    public static class WindowTransformCUI
    {
        private static RibbonItem TransformRibbonSeparator(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (typeof(Autodesk.Windows.RibbonSeparator) == item.GetType())
            {
                RibbonSeparator itemCUI = new RibbonSeparator(parent);
                Autodesk.Windows.RibbonSeparator itemWindow = item as Autodesk.Windows.RibbonSeparator;
                if (itemWindow.SeparatorStyle == Autodesk.Windows.RibbonSeparatorStyle.Spacer)
                {
                    itemCUI.SeparatorStyle = RibbonSeparatorStyle.Spacer;
                }
                else
                {
                    itemCUI.SeparatorStyle = RibbonSeparatorStyle.Line;
                }
                return itemCUI;
            }

            return null;
        }

        private static RibbonItem TransformRibbonRowPanel(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (typeof(Autodesk.Windows.RibbonRowPanel) == item.GetType())
            {
                RibbonRowPanel itemCUI = new RibbonRowPanel(parent);
                Autodesk.Windows.RibbonRowPanel itemWindow = item as Autodesk.Windows.RibbonRowPanel;

                RibbonRow row = new RibbonRow(itemCUI);
                itemCUI.Items.Add(row);

                foreach (Autodesk.Windows.RibbonItem i in itemWindow.Items)
                {
                    row = (RibbonRow)itemCUI.Items.Cast<RibbonItem>().Last(x => x is RibbonRow);
                    RibbonItem r = TransformRibbonItem(row, i);
                    if (r != null && typeof(RibbonRow) != r.GetType())
                    {
                        row.Items.Add(r);
                    }
                }
                return itemCUI;
            }

            return null;
        }

        private static RibbonItem TransformRibbonSplitButton(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (typeof(Autodesk.Windows.RibbonSplitButton) == item.GetType())
            {
                RibbonSplitButton itemCUI = new RibbonSplitButton(parent);
                Autodesk.Windows.RibbonSplitButton itemWindow = item as Autodesk.Windows.RibbonSplitButton;

                //ListStyle
                switch (itemWindow.ListStyle)
                {
                    case Autodesk.Windows.RibbonSplitButtonListStyle.Icon:
                        itemCUI.ListStyle = RibbonSplitButtonListStyle.Icon;
                        break;
                    case Autodesk.Windows.RibbonSplitButtonListStyle.List:
                        itemCUI.ListStyle = RibbonSplitButtonListStyle.IconText;
                        break;
                    case Autodesk.Windows.RibbonSplitButtonListStyle.Descriptive:
                        itemCUI.ListStyle = RibbonSplitButtonListStyle.Descriptive;
                        break;
                    default:
                        break;
                }

                //Items
                foreach (Autodesk.Windows.RibbonItem i in itemWindow.Items)
                {
                    RibbonItem r = TransformRibbonItem(itemCUI, i);
                    if (r != null)
                    {
                        itemCUI.Items.Add(r);
                    }
                }

                //Behavior
                itemCUI.Behavior = RibbonSplitButtonBehavior.SplitNoFollow;

                //ButtonStyle
                itemCUI.ButtonStyle = GetRibbonButtonStyle(itemWindow);

                //SmallImage  LargeImage

                //KeyTip
                itemCUI.KeyTip = itemWindow.KeyTip;

                //Grouping
                itemCUI.Grouping = itemWindow.IsGrouping;

                //Description
                itemCUI.Description = itemWindow.Description;

                //主要设置SmallImage  LargeImage
                _setRibbonSplitButton(itemCUI);

                return itemCUI;
            }

            return null;
        }

        private static RibbonItem TransformRibbonPanelBreak(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (typeof(Autodesk.Windows.RibbonPanelBreak) == item.GetType())
            {
                if (parent.Parent is RibbonPanelSource)
                {
                    RibbonPanelBreak itemCUI = new RibbonPanelBreak((RibbonPanelSource)parent.Parent);
                    ((RibbonPanelSource)parent.Parent).Items.Add(itemCUI);
                }
            }

            return null;
        }

        private static RibbonItem TransformRibbonRowBreak(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (typeof(Autodesk.Windows.RibbonRowBreak) == item.GetType() && typeof(RibbonRow) == parent.GetType())
            {
                RibbonRow itemCUI = new RibbonRow((RibbonItem)parent.Parent);

                if (parent.Parent is RibbonPanelSource)
                {
                    ((RibbonPanelSource)parent.Parent).Items.Add(itemCUI);
                }
                else if (parent.Parent is RibbonRowPanel)
                {
                    ((RibbonRowPanel)parent.Parent).Items.Add(itemCUI);
                }
                else
                {
                    throw new Exception("和作者预期不符");
                }

                return itemCUI;
            }
            return null;
        }

        private static RibbonItem TransformRibbonButton(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            if (item is Autodesk.Windows.RibbonButton)
            {
                RibbonCommandButton itemCUI = new RibbonCommandButton(parent);
                Autodesk.Windows.RibbonButton itemWindow = item as Autodesk.Windows.RibbonButton;

                itemCUI.ButtonStyle = GetRibbonButtonStyle(itemWindow);
                itemCUI.KeyTip = itemWindow.KeyTip;
                itemCUI.GroupName = itemWindow.GroupName;
                Autodesk.Windows.RibbonToolTip toolTip = itemWindow.ToolTip as Autodesk.Windows.RibbonToolTip;
                if (toolTip != null)
                {
                    itemCUI.TooltipTitle = toolTip.Content?.ToString();
                }
                if (itemWindow.CommandParameter != null)
                {
                    itemCUI.MacroID = _macros[itemWindow.CommandParameter.ToString()].ElementID;
                }

                return itemCUI;
            }

            return null;
        }

        private static RibbonButtonStyle GetRibbonButtonStyle(Autodesk.Windows.RibbonButton button)
        {
            if (button.ShowText && button.Size == Autodesk.Windows.RibbonItemSize.Large && button.Orientation == System.Windows.Controls.Orientation.Vertical)
            {
                return RibbonButtonStyle.LargeWithText;
            }
            else if (button.ShowText && button.Size == Autodesk.Windows.RibbonItemSize.Large && button.Orientation == System.Windows.Controls.Orientation.Horizontal)
            {
                return RibbonButtonStyle.LargeWithHorizontalText;
            }
            else if (button.ShowText && button.Size == Autodesk.Windows.RibbonItemSize.Standard && button.Orientation == System.Windows.Controls.Orientation.Vertical)
            {
                return RibbonButtonStyle.SmallWithText;
            }
            else if (!button.ShowText && button.Size == Autodesk.Windows.RibbonItemSize.Standard && button.Orientation == System.Windows.Controls.Orientation.Vertical)
            {
                return RibbonButtonStyle.SmallWithoutText;
            }

            return RibbonButtonStyle.LargeWithText;
        }



        /// <summary>
        /// Window的Ribbon类转换为CUI的Ribbon类，（不全，可日后补充）
        /// </summary>
        private static Dictionary<string, Func<RibbonItem, Autodesk.Windows.RibbonItem, RibbonItem>> TransformFunc
            = new Dictionary<string, Func<RibbonItem, Autodesk.Windows.RibbonItem, RibbonItem>>()
        {
            { nameof(TransformRibbonSeparator),TransformRibbonSeparator },
            { nameof(TransformRibbonRowPanel),TransformRibbonRowPanel },
            { nameof(TransformRibbonSplitButton),TransformRibbonSplitButton },
            { nameof(TransformRibbonPanelBreak),TransformRibbonPanelBreak },
            { nameof(TransformRibbonButton),TransformRibbonButton },
            { nameof(TransformRibbonRowBreak),TransformRibbonRowBreak },
        };


        /// <summary>
        /// 转换为CUI的Ribbon类（基本的转换）
        /// </summary>
        /// <param name="parent"></param>
        /// <param name="item"></param>
        /// <returns></returns>
        private static RibbonItem TransformRibbonItem(RibbonItem parent, Autodesk.Windows.RibbonItem item)
        {
            foreach (KeyValuePair<string, Func<RibbonItem, Autodesk.Windows.RibbonItem, RibbonItem>> i in TransformFunc)
            {
                RibbonItem r = i.Value?.Invoke(parent, item);

                if (r == null)
                    continue;

                r.Text = item.Text;
                return r;
            }

            return null;
        }

        /// <summary>
        /// 转换为CUI的RibbonPanelSource
        /// </summary>
        /// <param name="root"></param>
        /// <param name="item"></param>
        /// <param name="macros"></param>
        /// <returns></returns>
        private static RibbonPanelSource Transform(RibbonRoot root, Autodesk.Windows.RibbonPanelSource item)
        {
            RibbonPanelSource panel = new RibbonPanelSource(root);
            panel.Name = item.Name;
            panel.Text = item.Title;
            panel.KeyTip = item.KeyTip;

            RibbonRow row = new RibbonRow(panel);
            panel.Items.Add(row);

            foreach (Autodesk.Windows.RibbonItem i in item.Items)
            {
                row = (RibbonRow)panel.Items.Cast<RibbonItem>().Last(x => x is RibbonRow); ;
                RibbonItem r = WindowTransformCUI.TransformRibbonItem(row, i);
                if (r != null && typeof(RibbonRow) != r.GetType())
                {
                    row.Items.Add(r);
                }
            }

            return panel;
        }


        private static Dictionary<string, MenuMacro> _macros;
        private static Action<RibbonSplitButton> _setRibbonSplitButton;

        /// <summary>
        /// 转换为CUI
        /// </summary>
        /// <param name="root"></param>
        /// <param name="item"></param>
        /// <param name="macros"></param>
        /// <param name="setRibbonSplitButton"></param>
        public static void Transform(this RibbonRoot root, Autodesk.Windows.RibbonTab item, Dictionary<string, MenuMacro> macros, Action<RibbonSplitButton> setRibbonSplitButton)
        {
            _macros = macros;
            _setRibbonSplitButton = setRibbonSplitButton;

            foreach (Autodesk.Windows.RibbonPanel i in item.Panels)
            {
                RibbonPanelSource panel = Transform(root, i.Source);
                root.RibbonPanelSources.Add(panel);
            }

            RibbonTabSource tab = new RibbonTabSource(root);
            tab.Name = item.Name;
            tab.Text = item.Title;
            tab.KeyTip = item.KeyTip;

            foreach (RibbonPanelSource i in root.RibbonPanelSources)
            {
                RibbonPanelSourceReference rpsr = new RibbonPanelSourceReference(tab);
                rpsr.PanelId = i.ElementID;
                tab.Items.Add(rpsr);
            }

            root.RibbonTabSources.Add(tab);

            _macros = null;
            _setRibbonSplitButton = null;
        }
    }
}
